package com.choupin.choupin.admin.service.impl;

import com.choupin.choupin.admin.entity.Administration;
import com.choupin.choupin.admin.entity.Authentication;
import com.choupin.choupin.admin.entity.Personal;
import com.choupin.choupin.admin.mapper.AdminMapper;
import com.choupin.choupin.admin.service.IAdminService;
import com.choupin.choupin.admin.service.exception.AuthenticationNotUseException;
import com.choupin.choupin.admin.service.exception.ConferredUponByTheEmperorException;
import com.choupin.choupin.entity.Member;
import com.choupin.choupin.entity.Mine;
import com.choupin.choupin.entity.User;
import com.choupin.choupin.interceptor.MyLoginInterceptor;
import com.choupin.choupin.service.exception.*;
import com.choupin.choupin.utils.MD5AndSalt;
import com.choupin.choupin.utils.images.ImagesUtils;
import com.choupin.choupin.utils.redis.RedisHashUtil;
import com.choupin.choupin.utils.redis.RedisUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.text.SimpleDateFormat;
import java.time.Duration;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;

@SuppressWarnings("ALL")
@Service
public class AdminServiceImpl implements IAdminService {
    private static final  Integer AVATAR_MAX_SIZE=600*1024;
    private  static final List<String> AVATARTYPE=new ArrayList<>();
    private  static final  String LOCAL_UPLOAD_PATH_ADMIN="D:/choupin/src/main/resources/static/upload/avatar/admin";
    private  static final  String LOCAL_FRONT_PATH_ADMIN="D:/uniapp/choupinSaveImage/static/avatar/admin/";
    static {
        AVATARTYPE.add("image/jpeg");
        AVATARTYPE.add("image/png");
        AVATARTYPE.add("image/jpg");
    }


    @Autowired
     private AdminMapper adminMapper;

      @Autowired
      private RedisUtils redisUtils;

    @Autowired
    MyLoginInterceptor loginInterceptor;

    @Override
    public void register(Administration administration) {
//        参数校验
        if (administration==null){
            throw new ParameterIsEmptyException("参数为空！");
        }
        //先通过账号，查询数据库是否注册过该管理员，
        String phone=administration.getPhone();
         Administration a=adminMapper.selectPhone(phone);
        if (a!=null){
            // 如果是则直接返回提示“账号已注占用”
            throw  new SelectExcepion("账号已注占用！");
        }
//        判断验证码是否有效
        Authentication authentication=adminMapper.selectCode(administration.getAuthentication(),0);
        if (authentication==null){
            throw new AuthenticationNotUseException("验证码不存在或失效了");
        }
        //否则，对账号进行注册
        //生成一个随即昵称
        Random random=new Random();
         administration.setNickname("管理员"+random.nextInt(1000));

        administration.setCreatedUser(administration.getPhone());
        administration.setModifiedUser(administration.getPhone());

        LocalDateTime now=LocalDateTime.now();
        DateTimeFormatter formatter=DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        String nowdateString=now.format(formatter);
        LocalDateTime localDateTime=LocalDateTime.parse(nowdateString,formatter);
        administration.setCreatedTime(localDateTime);
        administration.setModifiedTime(localDateTime);
        //加密密码
        String salt= UUID.randomUUID().toString().toUpperCase();
        administration.setSalt(salt);
        String password= MD5AndSalt.getMD5Password(administration.getPassword(),salt);
        administration.setPassword(password);
//         计算年龄
        Date nowTime= new Date();
        Instant instant1=administration.getBirthday().toInstant();
        Instant instant2=nowTime.toInstant();
        Duration duration=Duration.between(instant1,instant2);
        if (duration.toDays()/365<1){
            administration.setAge(1);
        }else {
            administration.setAge((int) (duration.toDays()/365));
        }
//         设置默认头像
        administration.setAvatar("/static/avatar/default/defaultuser.png");
//        设置账号状态
        administration.setIsDelete(0);
//        注册账户
        adminMapper.insertAdmin(administration);
//       验证码失效
      Integer result= adminMapper.updateAuthenticationStatus(administration.getAuthentication(),1);
      if (result!=1||result==null){
          throw new UpdateException("更新错误！");
      }
        System.out.println("添加管理员成功！");

    }

    @Override
    public void login(String phone,String password) {
//        参数校验
        if (phone==null&&password==null){
            throw new ParameterIsEmptyException("参数为空！");
        }
        //先判断这个账号注册没有
        Administration administration=adminMapper.selectPhone(phone);
        System.out.println("管理员信息："+administration);
        if (administration==null){
            throw  new SelectExcepion("账号没有注册，请先注册账号！");
        }
//        判断封号
        if (administration.getIsDelete()==1){
            throw new ConferredUponByTheEmperorException("账号被封禁！");
        }

        //比较密码
        password=MD5AndSalt.getMD5Password(password,administration.getSalt());
        if(password.equals(administration.getPassword())){
//        存入redis缓存中，用于后续登录判断
            redisUtils.addRedis("admin_phone:"+phone,phone);
            redisUtils.addRedis("admin_password:"+phone,password);
//        获取当前时间
            String time=LocalDateTime.now().toString();
//        将当前登录的时间存入，redis中用于登录失效判断
            redisUtils.addRedis("admin_time:"+phone,time);
            System.out.println("已经将电话号码存入redis中！");
            System.out.println("从redis中取出："+redisUtils.getValue("admin_phone:"+phone));
        }else {
            throw new PasswordException("密码错误！");
        }
    }

    @Override
    public Personal showPersonal(String phone) {
//        参与校验
        if (phone==null){
            throw new PasswordException("查看个人信息的手机号为空！");
        }
        Administration administration=adminMapper.selectPhone(phone);
//        查询校验
        if (administration==null){
            throw new SelectExcepion("用户不存在！");
        }
//            计算年龄
            Date nowTime= new Date();
            Instant instant1=administration.getBirthday().toInstant();
            Instant instant2=nowTime.toInstant();
            Duration duration=Duration.between(instant1,instant2);
            SimpleDateFormat format=new SimpleDateFormat("yyyy-MM-dd");
            String birthdaystr=format.format(administration.getBirthday());
            if ((duration.toDays()/365)>administration.getAge()){
                User user1=new User();
                administration.setAge((int) (duration.toDays()/365));
                Integer result=adminMapper.updatePersonal(administration.getPhone(),administration.getAge(),administration.getNickname(),administration.getPassword(),administration.getGender(),administration.getBirthday(),birthdaystr);
                if (result==null){
                    throw new UpdateException("年龄更新失败！");
                }
                System.out.println("年龄自动更新");
            }
//            封装数据
            Personal personal=new Personal(administration.getId(),administration.getPhone(),administration.getAge(),administration.getPassword(),administration.getNickname(),administration.getGender(),administration.getBirthday(),administration.getAvatar());
            return personal;
    }

    @Override
    public void uploadAvatar(MultipartFile file,String phone){
        if (file.isEmpty()){
            throw new FileEmptyException("文件上传异常！文件不能为空");
        }
        if (file.getSize()>AVATAR_MAX_SIZE){
            throw new FileSizeException("文件上传异常！文件大小超过上限:"+AVATAR_MAX_SIZE);
        }
        if (!AVATARTYPE.contains(file.getContentType())){
            throw new FileTypeException("文件上传异常！文件类型不正确，允许的类型有："+AVATARTYPE);
        }
        //生成文件名
        String ofilename=file.getOriginalFilename();
        Integer index=ofilename.lastIndexOf(".");
        String suffix="";
        if (index!=-1){
            suffix=ofilename.substring(index);
        }
        String filename= UUID.randomUUID().toString()+suffix;

        //生成目标路径
//        String filePath=request.getServletContext().getRealPath("upload");
        String filePath=LOCAL_UPLOAD_PATH_ADMIN;  //将它保存到本地计算机指定路径
        String filePath2=LOCAL_FRONT_PATH_ADMIN;
        File parent=new File(filePath);//备份服务器路径
        File parent2=new File(filePath2);//备份到前端
        if (!parent.exists()){
            parent.mkdirs();
        }
        if (!parent2.exists()){
            parent2.mkdirs();
        }
        //将用户上传的头像上传到服务器
//        File dest=new File(uploadDir,filename);
        File dest=new File(parent,filename);
//      由于没有服务器于是备到前端项目
        File dest2=new File(parent2,filename);

        try {
            file.transferTo(dest);
//            备份到前端
            Files.copy(dest.toPath(),dest2.toPath());
        } catch (Exception e) {
            e.printStackTrace();
        }

        String avatar="http://10.102.228.179:5173/static/avatar/admin/"+filename; //存入服务器的路径，当前没有服务器，暂时改为本计算机的本项目路径做测试
//        将文件路径存入数据库
        Integer result=adminMapper.updateAvatarToPhone(phone,avatar);
        if (result!=1){
            throw new UpdateException("头像更新失败！");
        }
        System.out.println("用户："+phone+"图片"+avatar+"上传成功！");
    }

    @Override
    public void updatePersonal(Administration administration, String newPassword, String confirmPassword) {
        if (administration==null){
            throw new ParameterIsEmptyException("参数为空！");
        }
        if (administration.getPhone()==null){
            throw new ParameterIsEmptyException("手机号为空！");
        }
//        查询数据库
        Administration selectAdmin=adminMapper.selectPhone(administration.getPhone());
        if (selectAdmin==null){
            throw new SelectExcepion("用户信息不存在！");
        }
//        判断需要更新的数据
        if (administration.getNickname().equals(selectAdmin.getNickname())){
            administration.setNickname(null);
        }
        if (administration.getGender()==selectAdmin.getGender()){
            administration.setGender(null);
        }
        SimpleDateFormat dateFormat=new SimpleDateFormat("yyyy-MM-dd");
        String birthdayOld=dateFormat.format(selectAdmin.getBirthday());
        String birthdayNew=dateFormat.format(administration.getBirthday());
        System.out.println("更新的日期字符串为："+birthdayNew);
        if (birthdayNew.equals(birthdayOld)){
            administration.setBirthday(null);
            administration.setAge(null);
            birthdayNew=null;
        }else {
            //   计算年龄
            Date nowTime= new Date();
            Instant instant1=administration.getBirthday().toInstant();
            Instant instant2=nowTime.toInstant();
            Duration duration=Duration.between(instant1,instant2);
            Integer age=(int)duration.toDays()/365;
            if (age<1){
                administration.setAge(1);
            }else {
                administration.setAge(age);
            }
        }
//      判断密码是否更新
        if (administration.getPassword()!=null&&newPassword!=null&&confirmPassword!=null){
//           原密码不一致
            administration.setPassword(MD5AndSalt.getMD5Password(administration.getPassword(),selectAdmin.getSalt()));
            if (!administration.getPassword().equals(selectAdmin.getPassword())){
                throw new OldPasswordErrorException("原密码不正确！");
            }
//           新密码和确认密码是否一致
            if (!newPassword.equals(confirmPassword)){
                throw new PasswordInconsistencyException("新密码和确认密码不一致！");
            }
//            将原来密码替换成新密码
            administration.setPassword(MD5AndSalt.getMD5Password(newPassword,selectAdmin.getSalt()));
        }else {
            administration.setPassword(null);
        }
        System.out.println("更新的个人性别："+administration.getGender());
//        更新个人数据
        Integer result=adminMapper.updatePersonal(administration.getPhone(),administration.getAge(),administration.getNickname(),administration.getPassword(),administration.getGender(),administration.getBirthday(),birthdayNew);
        if (result!=1){
            throw new UpdateException("更新个人信息失败！");
        }
        System.out.println("管理员更新个人数据成功："+administration.getPhone());

    }

    @Override
    public void logout(String phone) {
        //        参数校验
        if (phone==null){
            throw  new ParameterIsEmptyException("参数为空");
        }
//         删除redis中会话信息
        RedisUtils.deleteKeyValue("admin_phone:"+phone);
        RedisUtils.deleteKeyValue("admin_password:"+phone);
        RedisUtils.deleteKeyValue("admin_time:"+phone);
        System.out.println("用户："+phone+"成功注销账户退出系统");
    }

    @Override
    public void loginInterceptor(String phone) {
        Boolean result=loginInterceptor.LoginInterceptor(phone,"admin_phone:"+phone,"admin_time:"+phone);
        System.out.println("result是个什么情况："+result);
        if (result==false){
            throw new LoginErrorxception("请先登录");
        }
    }

}
